<template>
  <div class="page">
    <main-card :title="detailData.name" :show-screen-space="false" :crumbs="crumbs">
      <template #tool-btn>
        <a-dropdown placement="bottom" @click.stop>
          <a-button class="icon-only-btn" @click.stop>
            <i class="iconfont icon-more-line"></i>
          </a-button>
          <template #overlay>
            <a-menu>
              <a-menu-item
                class="menu-icon-item"
                :disabled="detailData.trainStatus !== TrainingStatus.Success"
                @click="deployTask(detailData)"
              >
                部署任务
              </a-menu-item>
              <a-menu-item
                class="menu-icon-item"
                :disabled="detailData.trainStatus !== TrainingStatus.Success"
                @click="forecastTask(detailData)"
              >
                预测任务
              </a-menu-item>
              <a-menu-item
                class="menu-icon-item"
                :disabled="detailData.trainStatus !== TrainingStatus.Success"
                @click="onLineExport(detailData)"
              >
                在线导出
              </a-menu-item>
              <a-menu-item
                class="menu-icon-item"
                :disabled="detailData.trainStatus !== TrainingStatus.Success"
                @click="localExport(detailData.id)"
              >
                本地导出
              </a-menu-item>
              <a-menu-item
                v-if="checkPermissions(detailData?.createType, detailData?.readOnly)"
                class="menu-icon-item"
                @click="openDeleteTaskModal"
              >
                删除任务
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </template>
      <div class="detail-content">
        <div class="detail-header">
          <div class="header-content">
            <div class="content-title">创建时间</div>
            <div class="content-detail">{{ detailData.createTime }}</div>
          </div>
        </div>
        <div class="detail-content-body">
          <div class="content-card">
            <div>
              <div class="card-class-title">基础信息</div>
              <div class="card-list">
                <div class="list-title">任务名称</div>
                <div class="list-text" :title="detailData.name">{{ detailData.name }}</div>
              </div>
              <div class="card-list">
                <div class="list-title">任务类型</div>
                <div class="list-text">{{ getTaskTypeOptions(detailData.typeId)?.label }}</div>
              </div>
              <div class="card-list">
                <div class="list-title">模型名称</div>
                <div class="list-text" :title="detailData.modelName">{{ detailData.modelName }}</div>
              </div>
              <div class="card-list">
                <div class="list-title">训练状态</div>
                <div class="list-text" :title="getTrainingStatusObj(detailData.trainStatus).text">
                  {{ getTrainingStatusObj(detailData.trainStatus).text }}
                </div>
              </div>
              <div class="card-list">
                <div class="list-title">服务状态</div>
                <div class="list-text" :title="getDeployStatusObj(detailData.deployStatus).text">
                  {{ getDeployStatusObj(detailData.deployStatus).text }}
                </div>
              </div>
              <div class="card-list">
                <div class="list-title">运行日志</div>
                <div class="list-text"><a-button type="link" :disabled="isTaskCreating" @click="codeLogFn">查看</a-button></div>
              </div>
            </div>
            <div>
              <div class="card-class-title">资源分配</div>
              <div class="card-list">
                <div class="list-title">内存限制</div>
                <div class="list-text" :title="String(detailData.memory)">{{ detailData.memory }}GB</div>
              </div>
              <div class="card-list">
                <div class="list-title">CPU限制</div>
                <div class="list-text" :title="String(detailData.cpu)">{{ detailData.cpu }}Core</div>
              </div>
              <div class="card-list">
                <div class="list-title">显存限制</div>
                <div class="list-text" :title="String(detailData.gpu)">{{ detailData.gpu }}GB</div>
              </div>
            </div>
          </div>
          <div class="detail-frame">
            <div class="frame-content">
              <div class="frame-title">
                训练集
                <span>（{{ dataNameMap.length }}项）</span>
              </div>
              <template v-if="dataNameMap.length">
                <div class="frame-list">
                  <div v-for="name in dataNameMap" :key="name" class="frame-item">
                    <div class="list-left">
                      <div class="elliptical-1" :title="name">
                        {{ name }}
                      </div>
                    </div>
                  </div>
                </div>
              </template>

              <div v-else class="fc">
                <img class="empty-status-img mt-76" src="@/assets/img/empty-status.png" />
              </div>
            </div>
            <div class="frame-content">
              <div class="frame-title flex">
                <div class="max-w-280 w-280">
                  运行参数
                  <span>（{{ paramList.length }}项）</span>
                </div>
                <div class="max-w-180 w-180 ml-16">值</div>
              </div>
              <div class="frame-list">
                <template v-if="paramList.length">
                  <div v-for="item in paramList" :key="item.name" class="params-item">
                    <div class="elliptical-1 max-w-280 w-280 h-37 lh-37" :title="item.name">{{ item.name }}</div>
                    <div class="elliptical-1 max-w-180 w-180 ml-16 h-37 lh-37" :title="item.value">{{ item.value }}</div>
                  </div>
                </template>
                <div v-else class="fc">
                  <img class="empty-status-img mt-40" src="@/assets/img/empty-status.png" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </main-card>
  </div>
  <delete-confirm-dialog v-model:show="isDeleteDialogShow" :loading="confirmLoading" :confirm-name="detailData.name" @ok="onOkDeleteTask" />

  <online-export-from ref="onLineExportRef" v-model:show="showLineExport" :loading="okBtnLoading" @submit="onLineExportSubmit" />

  <code-log-modal ref="codeLogModalRef" />
</template>

<script setup lang="ts">
  import { message, Modal } from 'ant-design-vue'
  import { onMounted, reactive, ref } from 'vue'
  import { computed } from 'vue'
  import { createVNode } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRoute, useRouter } from 'vue-router'

  import WarnIcon from '@/components/icon/IconWarn/index.vue'
  import { modelTrainingApi } from '@/services/api'
  import { checkPermissions } from '@/utils/share'

  import OnlineExportFrom from '../components/OnlineExportFrom.vue'
  import { useTaskListDrawerStore } from '../components/TaskListDrawer/store'
  import { trainingSetDict } from '../options'
  import { DeployStatus, TaskDetail, TrainingStatus } from '../types'
  import { getDeployStatusObj, getTaskTypeOptions, getTrainingStatusObj } from '../utils'
  import codeLogModal from './components/CodeLogModal.vue'

  const router = useRouter()
  const route = useRoute()

  const taskId = route.params.id as string
  const crumbs = [{ name: '模型训练', path: '/modal-training/list' }, { name: '任务详情' }]

  const detailData = reactive<TaskDetail>({
    createTime: '',
    id: '',
    name: '',
    typeId: 1,
    modelName: '',
    trainStatus: 1,
    deployStatus: 1,
    memory: 0,
    gpu: 0,
    cpu: 0,
    dataNames: [],
    runParameters: []
  })
  //用于展示的训练集对象
  const dataNameMap = computed(() => {
    return detailData.dataNames
      .map(name => trainingSetDict[name])
      .map(item => (detailData.typeId === 1 ? `${item.parent}/${item.name}` : item.name))
  })
  const paramList = ref<{ name: string; value: string }[]>([])

  const getDetailFn = async () => {
    let { data } = await modelTrainingApi.info({}, { urlParams: { id: taskId } })

    crumbs[1].name = data.name

    Object.assign(detailData, data)

    paramList.value = data.runParameters
  }

  /* 在线导出------------------------------------------------------------------------------------- */
  const { changeTaskListOptions } = useTaskListDrawerStore()

  const showLineExport = ref(false)
  const onLineExportRef = ref<InstanceType<typeof OnlineExportFrom>>()

  const { loading: okBtnLoading, runAsync: runOnlineExport } = useRequest(modelTrainingApi.onlineExport)
  const onLineExportSubmit = async (formData: any) => {
    await runOnlineExport(formData)
    showLineExport.value = false
    changeTaskListOptions({ open: true, key: '1' })
  }
  const onLineExport = (record: TaskDetail) => {
    onLineExportRef.value?.setFormState(record)
    showLineExport.value = true
  }

  /* 本地导出------------------------------------------------------------------------------------- */

  const localExport = async (recordId: string) => {
    await modelTrainingApi.localExport({}, { urlParams: { id: recordId } })
    changeTaskListOptions({ open: true, key: '2' })
  }

  /* 部署逻辑------------------------------------------------------------------------------------------------------------- */
  const { loading: isDeployLoading, runAsync: runDeployTask } = useRequest(modelTrainingApi.deploy, {
    onSuccess: () => {
      message.success('操作成功')
      getDetailFn()
    }
  })

  const deployTask = (record: TaskDetail) => {
    if ([DeployStatus.NotDeployed].includes(record.deployStatus)) {
      Modal.confirm({
        icon: createVNode(WarnIcon),
        content: `请确认是否部署此任务服务？`,
        okButtonProps: {
          type: 'default',
          loading: isDeployLoading.value
        },
        centered: true,
        onOk: () => {
          runDeployTask({ id: record.id })
        }
      })
    } else if ([DeployStatus.ToBeDeployed, DeployStatus.Deploying].includes(record.deployStatus)) {
      Modal.warning({
        icon: createVNode(WarnIcon),
        content: `服务正在部署，请耐心等待`,
        okButtonProps: {
          type: 'default'
        },
        centered: true
      })
    } else if (
      [
        DeployStatus.DeploymentSuccessful,
        DeployStatus.DeploymentFailed,
        DeployStatus.DeploymentTimeout,
        DeployStatus.DeploymentPastDue
      ].includes(record.deployStatus)
    ) {
      Modal.confirm({
        icon: createVNode(WarnIcon),
        content: `请确认是否重新部署此任务服务？`,
        okButtonProps: {
          type: 'default',
          loading: isDeployLoading.value
        },
        centered: true,
        onOk: async () => {
          runDeployTask({ id: record.id })
        }
      })
    }
  }

  /* 预测逻辑------------------------------------------------------------------------------------------------------------- */
  const { runAsync: runForecastTask } = useRequest(modelTrainingApi.forecast)

  const forecastTask = async (record: TaskDetail) => {
    if ([DeployStatus.NotDeployed].includes(record.deployStatus)) {
      Modal.confirm({
        icon: createVNode(WarnIcon),
        title: `此服务暂未部署，无法使用预测功能，请您先部署该任务服务`,
        okButtonProps: {
          type: 'default',
          loading: isDeployLoading.value
        },
        okText: '部署',
        centered: true,
        onOk: () => {
          runDeployTask({ id: record.id })
        }
      })
    } else if ([DeployStatus.ToBeDeployed, DeployStatus.Deploying].includes(record.deployStatus)) {
      Modal.warning({
        icon: createVNode(WarnIcon),
        title: `服务正在部署，请耐心等待`,
        okButtonProps: {
          type: 'default'
        },
        centered: true
      })
    } else if (
      [DeployStatus.DeploymentFailed, DeployStatus.DeploymentTimeout, DeployStatus.DeploymentPastDue].includes(record.deployStatus)
    ) {
      Modal.confirm({
        icon: createVNode(WarnIcon),
        title: `任务无法预测，请您重新部署该任务服务`,
        okButtonProps: {
          type: 'default',
          loading: isDeployLoading.value
        },
        centered: true,
        okText: '重新部署',
        onOk: async () => {
          runDeployTask({ id: record.id })
        }
      })
    } else if ([DeployStatus.DeploymentSuccessful].includes(record.deployStatus)) {
      await runForecastTask(
        {},
        {
          urlParams: {
            id: record.id
          }
        }
      )
      router.push(`/modal-training/predicted/${record.id}`)
    }
  }

  /* 删除测试任务 ----------------------------------------------------------------- */
  const isDeleteDialogShow = ref(false)

  const openDeleteTaskModal = () => {
    isDeleteDialogShow.value = true
  }

  const { loading: confirmLoading, runAsync: runDelModelTraining } = useRequest(modelTrainingApi.del)
  const onOkDeleteTask = async () => {
    await runDelModelTraining({}, { urlParams: { id: taskId } })
    message.success('操作成功')
    isDeleteDialogShow.value = false
    router.back()
  }
  /* 日志----------------------------------------------------------------- */
  // 是否任务创建中
  const isTaskCreating = computed(() => [TrainingStatus.Waiting].includes(detailData.trainStatus))

  // 查看运行日志
  const codeLogModalRef = ref()

  const codeLogFn = () => {
    codeLogModalRef.value?.open(taskId)
  }
  /* ----------------------------------------------------------------- */

  onMounted(() => {
    getDetailFn()
  })
</script>

<style lang="less" scoped>
  .page {
    width: 100%;
  }

  .detail-header {
    display: flex;
    align-items: center;
    padding: 10px 24px;
    height: 58px;
    gap: 24px;
    border-bottom: 1px solid @mask1;
    background: @background1;

    .header-content {
      display: flex;
      height: 20px;

      &:first-child {
        box-sizing: border-box;
        padding-right: 24px;
      }

      .content-title {
        margin-right: 16px;
        font-size: 12px;
        color: @text03;
        font-style: normal;
        font-weight: 400;
        line-height: 20px;
      }

      .content-detail {
        font-size: 14px;
        color: @text01;
        font-style: normal;
        font-weight: 400;
        line-height: 20px;
      }
    }
  }

  .detail-content-body {
    display: flex;
  }

  .detail-content {
    overflow: hidden;
    // display: flex;
    margin-top: 12px;
    border: 1px solid @border1;
    border-radius: 10px;

    .content-card {
      display: flex;
      padding: 36px 40px;
      width: 840px;
      height: 578px;
      background-color: @background2;
      box-sizing: border-box;
      gap: 20px;

      & > div {
        width: 50%;
      }

      .card-class-title {
        margin-bottom: 16px;
        color: @text01;
        .font18b();
      }

      .card-list {
        display: flex;
        margin-bottom: 40px;
        width: 100%;
        height: 36px;

        .list-title {
          width: 80px;
          min-width: 80px;
          font-size: 14px;
          font-style: normal;
          font-weight: 400;
          line-height: 36px;
          color: rgba(25, 25, 48, 0.75);
          .elliptical-1();
        }

        .list-text {
          margin-left: 8px;
          // width: 224px;
          font-size: 14px;
          font-style: normal;
          font-weight: 700;
          line-height: 36px;

          i {
            margin-right: 6px;
            font-size: 14px;
            color: #4686ed;
          }
          .elliptical-1();
        }
      }
    }

    .detail-frame {
      display: flex;
      height: 578px;
      background-color: @background1;
      flex: 1;
      flex-wrap: wrap;

      .frame-content {
        overflow: auto;
        width: 100%;
        min-width: 50%;
        height: 50%;

        &:nth-child(1) {
          border-right: 1px solid @background5;
        }

        &:nth-child(3) {
          border-right: 1px solid @background5;
        }

        .frame-title {
          display: flex;
          align-items: center;
          padding-left: 16px;
          width: 100%;
          height: 38px;
          font-size: 14px;
          background: @background3;
          font-style: normal;
          font-weight: 700;
          line-height: 38px;
          border-top: 1px solid @background5;
          border-bottom: 1px solid @background5;

          span {
            margin-left: 4px;
            font-size: 12px;
            color: @text03;
            font-style: normal;
            font-weight: 400;
          }
        }

        .frame-list {
          overflow: auto;
          height: calc(100% - 38px);
          // 运行参数元素
          .params-item {
            display: flex;
            align-items: center;
            padding: 0 16px;
            width: 100%;
            height: 38px;
            border-bottom: 1px solid #ebebeb;
          }

          .frame-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 0 16px;
            width: 100%;
            min-width: 100%;
            max-width: 100%;
            height: 38px;
            border-bottom: 1px solid #ebebeb;

            .delete-status {
              color: @text04;
            }

            .list-left {
              display: flex;
              justify-content: space-between;
              align-items: center;
              width: 480px;
              font-size: 14px;
              font-style: normal;
              font-weight: 400;
              line-height: 22px;

              i {
                margin-right: 8px;
                font-size: 14px;
              }

              .elliptical-1 {
                flex-grow: 1;
              }
            }

            .list-status {
              font-size: 12px;
              color: @text04;
              font-style: normal;
              font-weight: 400;
            }
          }
        }

        // 空状态图片
        .empty-status-img {
          width: 64px;
          height: 70px;
        }
      }
    }
  }
</style>
